package com.imax.center.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.imax.center.constant.EzvizApiConstants;
import com.imax.center.model.*;
import com.imax.center.service.EzvizTokenService;
import com.imax.center.model.EzvizBatchDeviceUrlResponse.DeviceUrlInfo;
import com.imax.center.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private EzvizTokenService ezvizTokenService;

    @Autowired
    private RestTemplate restTemplate;

    // 线程池，用于并发获取多个设备的URL
    private final ExecutorService executor = Executors.newFixedThreadPool(10);

    @Override
    public List<EzvizDevice> getAllDeviceList() {
        List<EzvizDevice> allDevices = new ArrayList<>();
        int pageStart = 0;
        int pageSize = 50;
        int total = 0;
        boolean hasMorePages = true;

        try {
            String accessToken = ezvizTokenService.getAccessToken();

            while (hasMorePages) {
                String url = String.format("%s?accessToken=%s&pageStart=%s&pageSize=%s",
                        EzvizApiConstants.DEVICE_LIST_URL, accessToken, pageStart, pageSize);

                String response = restTemplate.postForObject(url, null, String.class);
                JSONObject jsonResponse = JSONObject.parseObject(response);

                log.info("萤石云获取设备列表响应 (页: {})", pageStart);

                if (jsonResponse != null && "200".equals(jsonResponse.getString("code"))) {
                    // 解析当前页设备列表并添加到总列表中
                    List<EzvizDevice> pageDevices = JSONObject.parseArray(jsonResponse.getString("data"), EzvizDevice.class);
                    if (pageDevices != null) {
                        allDevices.addAll(pageDevices);
                    }

                    // 获取分页信息
                    JSONObject pageInfo = jsonResponse.getJSONObject("page");
                    if (pageInfo != null) {
                        total = pageInfo.getIntValue("total");
                        int size = pageInfo.getIntValue("size");

                        // 判断是否还有更多页
                        if (allDevices.size() >= total || pageDevices == null || pageDevices.isEmpty()) {
                            hasMorePages = false;
                        } else {
                            // 移动到下一页
                            pageStart += 1;
                        }
                    } else {
                        // 如果响应中没有分页信息，则假设已经获取了所有设备
                        hasMorePages = false;
                    }
                } else {
                    String errorMsg = jsonResponse != null ? jsonResponse.getString("msg") : "获取设备列表失败";
                    log.error("获取萤石云设备列表失败: {}", errorMsg);
                    return allDevices;
                }
            }

            log.info("成功获取所有萤石云设备，共{}个设备", allDevices.size());
            return allDevices;
        } catch (Exception e) {
            log.error("获取萤石云设备列表异常: ", e);
            return allDevices;
        }
    }

    @Override
    public List<EzvizChannel> getAllChannelList() {
        List<EzvizChannel> allDevices = new ArrayList<>();
        int pageStart = 0;
        int pageSize = 50;
        int total = 0;
        boolean hasMorePages = true;

        try {
            String accessToken = ezvizTokenService.getAccessToken();

            while (hasMorePages) {
                String url = String.format("%s?accessToken=%s&pageStart=%s&pageSize=%s",
                        EzvizApiConstants.CHANNEL_LIST_URL, accessToken, pageStart, pageSize);

                String response = restTemplate.postForObject(url, null, String.class);
                JSONObject jsonResponse = JSONObject.parseObject(response);

                log.info("萤石云获取通道列表响应 (页: {})", pageStart);

                if (jsonResponse != null && "200".equals(jsonResponse.getString("code"))) {
                    // 解析当前页通道列表并添加到总列表中
                    List<EzvizChannel> pageDevices = JSONObject.parseArray(jsonResponse.getString("data"), EzvizChannel.class);
                    if (pageDevices != null) {
                        allDevices.addAll(pageDevices);
                    }

                    // 获取分页信息
                    JSONObject pageInfo = jsonResponse.getJSONObject("page");
                    if (pageInfo != null) {
                        total = pageInfo.getIntValue("total");
                        int size = pageInfo.getIntValue("size");

                        // 判断是否还有更多页
                        if (allDevices.size() >= total || pageDevices == null || pageDevices.isEmpty()) {
                            hasMorePages = false;
                        } else {
                            // 移动到下一页
                            pageStart += 1;
                        }
                    } else {
                        // 如果响应中没有分页信息，则假设已经获取了所有通道
                        hasMorePages = false;
                    }
                } else {
                    String errorMsg = jsonResponse != null ? jsonResponse.getString("msg") : "获取通道列表失败";
                    log.error("获取萤石云通道列表失败: {}", errorMsg);
                    return allDevices;
                }
            }

            log.info("成功获取所有萤石云通道，共{}个通道", allDevices.size());
            return allDevices;
        } catch (Exception e) {
            log.error("获取萤石云通道列表异常: ", e);
            return allDevices;
        }
    }

    @Override
    public EzvizDeviceUrl getDeviceUrl(String deviceSerial, Integer channelNo, Integer type,
                                     String startTime, String stopTime, Integer playbackSpeed) {
        if (StringUtils.isEmpty(deviceSerial)) {
            throw new IllegalArgumentException("设备序列号不能为空");
        }

        // 设置默认值
        if (channelNo == null) {
            channelNo = 1;
        }
        if (type == null) {
            type = 1;
        }

        try {
            String accessToken = ezvizTokenService.getAccessToken();

            // 构建请求URL
            StringBuilder urlBuilder = new StringBuilder(EzvizApiConstants.DEVICE_LIVE_ADDRESS_URL);
            urlBuilder.append("?accessToken=").append(accessToken);
            urlBuilder.append("&deviceSerial=").append(deviceSerial);
            urlBuilder.append("&channelNo=").append(channelNo);
            urlBuilder.append("&type=").append(type);

            // 添加可选参数
            if (type > 1 && !StringUtils.isEmpty(startTime)) {
                urlBuilder.append("&startTime=").append(startTime);
            }
            if (type > 1 && !StringUtils.isEmpty(stopTime)) {
                urlBuilder.append("&stopTime=").append(stopTime);
            }
            if (type > 1 && playbackSpeed != null) {
                urlBuilder.append("&playbackSpeed=").append(playbackSpeed);
            }

            String url = urlBuilder.toString();
            log.info("获取萤石云设备URL请求: {}", url);

            String response = restTemplate.postForObject(url, null, String.class);
            JSONObject jsonResponse = JSONObject.parseObject(response);

            log.info("萤石云获取设备URL响应: {}", jsonResponse);

            if (jsonResponse != null && "200".equals(jsonResponse.getString("code"))) {
                JSONObject data = jsonResponse.getJSONObject("data");
                EzvizDeviceUrl deviceUrl = new EzvizDeviceUrl();

                // 设置请求参数
                deviceUrl.setDeviceSerial(deviceSerial);
                deviceUrl.setChannelNo(channelNo);
                deviceUrl.setType(type);
                deviceUrl.setStartTime(startTime);
                deviceUrl.setStopTime(stopTime);
                deviceUrl.setPlaybackSpeed(playbackSpeed);

                // 设置返回的URL
                deviceUrl.setUrl(data.getString("url"));

                return deviceUrl;
            } else {
                String errorMsg = jsonResponse != null ? jsonResponse.getString("msg") : "获取设备URL失败";
                log.error("获取萤石云设备URL失败: {}", errorMsg);
                throw new RuntimeException(errorMsg);
            }
        } catch (Exception e) {
            log.error("获取萤石云设备URL异常: ", e);
            throw new RuntimeException("获取设备URL失败", e);
        }
    }

    @Override
    public EzvizBatchDeviceUrlResponse getBatchDeviceUrls(EzvizBatchDeviceUrlRequest batchRequest) {
        log.info("批量获取设备URL请求: {}", batchRequest);

        if (batchRequest == null || batchRequest.getDevices() == null || batchRequest.getDevices().isEmpty()) {
            throw new IllegalArgumentException("设备列表不能为空");
        }

        EzvizBatchDeviceUrlResponse response = new EzvizBatchDeviceUrlResponse();
        List<DeviceUrlInfo> deviceUrlInfos = new ArrayList<>();

        // 使用CompletableFuture并发获取所有设备的URL
        List<CompletableFuture<DeviceUrlInfo>> futures = batchRequest.getDevices().stream()
                .map(deviceInfo -> CompletableFuture.supplyAsync(() -> {
                    DeviceUrlInfo urlInfo = new DeviceUrlInfo();
                    urlInfo.setDeviceSerial(deviceInfo.getDeviceSerial());
                    urlInfo.setChannelNo(deviceInfo.getChannelNo() != null ? deviceInfo.getChannelNo() : 1);

                    try {
                        // 复用现有的单设备URL获取方法
                        EzvizDeviceUrl deviceUrl = getDeviceUrl(
                                deviceInfo.getDeviceSerial(),
                                deviceInfo.getChannelNo(),
                                batchRequest.getType(),
                                batchRequest.getStartTime(),
                                batchRequest.getStopTime(),
                                batchRequest.getPlaybackSpeed()
                        );

                        // 设置返回的URL信息
                        urlInfo.setUrl(deviceUrl.getUrl());
                        urlInfo.setSuccess(true);
                    } catch (Exception e) {
                        log.error("获取设备URL失败，设备序列号: {}, 通道号: {}, 错误: {}",
                                deviceInfo.getDeviceSerial(), deviceInfo.getChannelNo(), e.getMessage());
                        urlInfo.setSuccess(false);
                        urlInfo.setErrorMessage(e.getMessage());
                    }

                    return urlInfo;
                }, executor))
                .collect(Collectors.toList());

        try {
            // 等待所有任务完成，超时时间为30秒
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                    .get(30, TimeUnit.SECONDS);

            // 收集所有设备URL结果
            for (CompletableFuture<DeviceUrlInfo> future : futures) {
                try {
                    deviceUrlInfos.add(future.get());
                } catch (Exception e) {
                    log.error("获取设备URL任务异常: ", e);
                }
            }
        } catch (Exception e) {
            log.error("批量获取设备URL超时: ", e);
        }

        response.setDeviceUrls(deviceUrlInfos);
        log.info("批量获取设备URL响应: {}", response);

        return response;
    }

    @Override
    public String captureDeviceImage(String deviceSerial, Integer channelNo) {
        log.info("设备抓拍请求，设备序列号: {}, 通道号: {}", deviceSerial, channelNo);

        if (StringUtils.isEmpty(deviceSerial)) {
            //抛出异常
            throw new RuntimeException("设备序列号不能为空");
        }

        // 设置默认值
        if (channelNo == null) {
            channelNo = 1;
        }
        int quality = 4;

        try {
            String accessToken = ezvizTokenService.getAccessToken();

            // 构建请求URL
            StringBuilder urlBuilder = new StringBuilder(EzvizApiConstants.DEVICE_CAPTURE_URL);
            urlBuilder.append("?accessToken=").append(accessToken);
            urlBuilder.append("&deviceSerial=").append(deviceSerial);
            urlBuilder.append("&channelNo=").append(channelNo);
            urlBuilder.append("&quality=").append(quality); //视频清晰度,0-流畅,1-高清(720P),2-4CIF,3-1080P,4-400w

            String url = urlBuilder.toString();
            log.info("萤石云设备抓拍请求: {}", url);

            String response = restTemplate.postForObject(url, null, String.class);
            JSONObject jsonResponse = JSONObject.parseObject(response);
            
            log.info("萤石云设备抓拍响应: {}", jsonResponse);
            
            if (jsonResponse != null && "200".equals(jsonResponse.getString("code"))) {
                JSONObject data = jsonResponse.getJSONObject("data");
                if (data != null) {
                    String picUrl = data.getString("picUrl");
                    if (!StringUtils.isEmpty(picUrl)) {
                        return picUrl;
                    }
                }
                //抛出异常
                log.info("设备抓拍失败，未获取到图片URL");
                return "";
            } else {
                String errorMsg = jsonResponse != null ? jsonResponse.getString("msg") : "设备抓拍失败";
                log.error("萤石云设备抓拍失败: {}", errorMsg);
                return "";
            }
        } catch (Exception e) {
            log.error("萤石云设备抓拍异常: ", e);
            return "";
        }
    }
}
